﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
#region using for special implements
using Com.ProjectA.Utility;
using Com.ProjectA.DAO;
using System.Data;
using System.Data.SqlClient;
using System.Data.Common;
using System.Configuration;
#endregion using for special implements
namespace Com.ProjectA.DAC
{
    public class DACConnectionManager
    {
        #region Declare variables
        private string _strConnectionString = null;
        //private SqlClientFactory _sqlClientFactory = null;
        //public SqlClientFactory sqlClientFactory { get { return _sqlClientFactory; } }
        private SqlConnection _sqlConnection = null;
        public SqlConnection sqlConnection { get { return _sqlConnection; } }
        //private DbConnection _dbConnection = null;
        //public DbConnection dbConnection { get { return _dbConnection; } }
        private bool _hasTransactionProcess;
        private SqlTransaction _sqlTransaction;
        public SqlTransaction sqlTransaction { get { return _sqlTransaction; } }
        #endregion Declare variables
        /// <summary>
        /// Constructure to get connection string from configuration file by connection name and recognize whether using transaction process or not
        /// <para>strConnectionName: Connection name</para>
        /// <para>hasTransactionProcess: Flag to recognize whether using transaction process or not. Default is false</para>
        /// </summary>
        /// <param name="strConnectionName">Connection name</param>
        /// <param name="hasTransactionProcess">Flag to recognize whether using transaction process or not. Default is false</param>
        public DACConnectionManager(string strConnectionName, bool hasTransactionProcess = false)
        {
            // Initiate connection string
            if (!String.IsNullOrWhiteSpace(strConnectionName)) 
            {
                _strConnectionString = ConfigurationManager.ConnectionStrings[strConnectionName] != null ? ConfigurationManager.ConnectionStrings[strConnectionName].ConnectionString : null;
                
                if (!String.IsNullOrWhiteSpace(_strConnectionString))
                {
                    // Initiate sql client factory
                    //_sqlClientFactory = SqlClientFactory.Instance;
                    _sqlConnection = new SqlConnection(_strConnectionString);
                    //_dbConnection = _sqlClientFactory.CreateConnection();
                    //_dbConnection.ConnectionString = _strConnectionString;
                    this._hasTransactionProcess = hasTransactionProcess;
                }
            }
        }

        /// <summary>
        /// Constructure to get connection string from creating instance of daoconnectioninfo, specified connection structure and recognize whether using transaction process or not
        /// <para>connectionStructure: Connection structs</para>
        /// <para>connectionStructureType: Connection struct types corresponding to defined structures</para>
        /// <para>daoConnectionInfo: Flag to recognize whether using transaction process or not. Default is false</para>
        /// <para>hasTransactionProcess: Flag to recognize whether using transaction process or not. Default is false</para>
        /// </summary>
        /// <param name="connectionStructureType">Connection struct types corresponding to defined structures</param>
        /// <param name="daoConnectionInfo">Flag to recognize whether using transaction process or not. Default is false</param>
        /// <param name="hasTransactionProcess">Flag to recognize whether using transaction process or not. Default is false</param>
        public DACConnectionManager(Constants.ConnectionStructureType connectionStructureType
            , DAOConnectionInfo daoConnectionInfo, bool hasTransactionProcess = false, string strConnectionString = null)
        {
            #region Initiate connection string
            switch (connectionStructureType)
            {
                case Constants.ConnectionStructureType.A:
                    {
                        _strConnectionString = String.Format(Constants.STR_CONN_STRING_STRUCTURE_STANDARD_SEC, daoConnectionInfo.strServerValue
                            , daoConnectionInfo.strDatabaseValue, daoConnectionInfo.strUserIdValue, daoConnectionInfo.strPasswordValue);
                        break;
                    }
                case Constants.ConnectionStructureType.B:
                    {
                        _strConnectionString = String.Format(Constants.STR_CONN_STRING_STRUCTURE_TRUSTED_CONN, daoConnectionInfo.strServerValue
                            , daoConnectionInfo.strDatabaseValue, daoConnectionInfo.strTrustedConnectionValue);
                        break;
                    }
                case Constants.ConnectionStructureType.C:
                    {
                        _strConnectionString = String.Format(Constants.STR_CONN_STRING_STRUCTURE_SQLSERVER_INSTANCE, daoConnectionInfo.strServerValue
                            , daoConnectionInfo.strDatabaseValue, daoConnectionInfo.strUserIdValue, daoConnectionInfo.strPasswordValue);
                        break;
                    }
                case Constants.ConnectionStructureType.D:
                    {
                        _strConnectionString = String.Format(Constants.STR_CONN_STRING_STRUCTURE_CE_DEVICE, daoConnectionInfo.strServerValue
                            , daoConnectionInfo.strDatabaseValue, daoConnectionInfo.strUserIdValue, daoConnectionInfo.strPasswordValue);
                        break;
                    }
                case Constants.ConnectionStructureType.E:
                    {
                        _strConnectionString = String.Format(Constants.STR_CONN_STRING_STRUCTURE_VIA_IP, daoConnectionInfo.strDataSourceValue
                            , daoConnectionInfo.strNetworkLibraryValue, daoConnectionInfo.strInitialCatalogValue, daoConnectionInfo.strUserIdValue
                            , daoConnectionInfo.strPasswordValue);
                        break;
                    }
                case Constants.ConnectionStructureType.F:
                    {
                        _strConnectionString = String.Format(Constants.STR_CONN_STRING_STRUCTURE_MARS, daoConnectionInfo.strServerValue, daoConnectionInfo.strDatabaseValue
                            , daoConnectionInfo.strTrustedConnectionValue, daoConnectionInfo.strMultipleActiveResultSetsValue);
                        break;
                    }
                case Constants.ConnectionStructureType.G:
                    {
                        _strConnectionString = String.Format(Constants.STR_CONN_STRING_STRUCTURE_ATTACH_LOCAL, daoConnectionInfo.strServerValue, daoConnectionInfo.strAttachDbFilenameValue
                            , daoConnectionInfo.strDatabaseValue, daoConnectionInfo.strTrustedConnectionValue);
                        break;
                    }
                case Constants.ConnectionStructureType.H:
                    {
                        _strConnectionString = String.Format(Constants.STR_CONN_STRING_STRUCTURE_ATTACH_LOCAL_USER_INSTANCE, daoConnectionInfo.strDataSourceValue
                            , daoConnectionInfo.strIntegratedSecurityValue, daoConnectionInfo.strAttachDbFilenameValue, daoConnectionInfo.strUserIdValue);
                        break;
                    }
                case Constants.ConnectionStructureType.K:
                    {
                        _strConnectionString = String.Format(Constants.STR_CONN_STRING_STRUCTURE_ASYN_PROCESS, daoConnectionInfo.strServerValue, daoConnectionInfo.strDatabaseValue
                            , daoConnectionInfo.strIntegratedSecurityValue, daoConnectionInfo.strAsynchronousProcessingValue);
                        break;
                    }
                default:
                    {
                        _strConnectionString = strConnectionString;
                        break;
                    }
            }
            #endregion Initiate connection string

            if (_strConnectionString != null)
            {
                // Initiate sql client factory
                //_sqlClientFactory = SqlClientFactory.Instance;
                _sqlConnection = new SqlConnection(_strConnectionString);
                this._hasTransactionProcess = hasTransactionProcess;
            }
        }

        /// <summary>
        /// Open connection with specified connection string
        /// </summary>
        /// <returns>False if can not create connection from connection string. True if creating connection is successful</returns>
        public bool OpenConnection()
        {
            if (_sqlConnection != null && !String.IsNullOrEmpty(_sqlConnection.ConnectionString))
            {
                _sqlConnection.Open();
                return true;
            }
            return false;
        }

        /// <summary>
        /// Close connection with defined connection string
        /// </summary>
        public void CloseConnection()
        {
            if (_sqlConnection != null && !_sqlConnection.State.Equals(ConnectionState.Closed))
            {
                _sqlConnection.Close();
            }
        }
        /// <summary>
        /// Begin transaction with defined db connection
        /// </summary>
        public void BeginTransaction()
        {
            if (_sqlConnection != null && _sqlConnection.State.Equals(ConnectionState.Open) && this._hasTransactionProcess)
            {
                this._sqlTransaction = _sqlConnection.BeginTransaction();
            }
        }
        /// <summary>
        /// Rollback transaction
        /// </summary>
        public void RollbackTransaction()
        {
            if (this._sqlTransaction != null)
            {
                this._sqlTransaction.Rollback();
            }
        }
        /// <summary>
        /// Commit transaction
        /// </summary>
        public void CommitTransaction()
        {
            if (_sqlConnection.State.Equals(ConnectionState.Open) && this._sqlTransaction != null)
            {
                this._sqlTransaction.Commit();
            }
        }
    }
}
